package fem2.material;

import inf.jlinalg.BLAM;
import inf.jlinalg.IVector;
import math2.FunctionBasisOnRnToR;
import fem2.BasisManager;
import fem2.Element;
import fem2.MaterialModel;
import fem2.MeshPart;
import fem2.Node;

/**
 * abstract class for all type of host material model for stress recovery
 * 
 * @author hbui
 * 
 */
public abstract class StressRecoveryMM extends HostMaterialModel {

	public StressRecoveryMM(MaterialModel mm) {
		super(mm);
	}

	/**
	 * compute recover stress at node
	 * 
	 * @param n
	 * @return
	 */
	public abstract IVector computeRecoverStress(Node n);

	/**
	 * compute recover stress at specific point in the element domain by
	 * interpolation from nodal (recovered) stress
	 * 
	 * @param e
	 * @param xi
	 * @return
	 */
	public IVector computeRecoverStress(Element e, double... xi) {
		MeshPart mp = e.getMeshPart();
		Node[] nodes = mp.getNodes();
		// FunctionBasisOnRnToR basis = mp.getBasis();
		FunctionBasisOnRnToR basis = BasisManager.getInstance().getBasis(mp.getType());
		IVector rStress = null;

		for (int i = 0; i < nodes.length; i++) {
			IVector tmp = computeRecoverStress(nodes[i]);
			double Ni = basis.getBasisFunction(i).valueAt(xi);
			if (rStress == null) {
				rStress = tmp;
				BLAM.scale(Ni, rStress);
			} else {
				BLAM.add(Ni, tmp, rStress);
			}
		}

		return rStress;
	}
}